home *** CD-ROM | disk | FTP | other *** search
- /***********************************************************************/
- /* BOX.C - */
- /* This file contains all functions relating to box operations. */
- /***********************************************************************/
- /*
- * THE - The Hessling Editor. A text editor similar to VM/CMS xedit.
- * Copyright (C) 1991-1995 Mark Hessling
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to:
- *
- * The Free Software Foundation, Inc.
- * 675 Mass Ave,
- * Cambridge, MA 02139 USA.
- *
- *
- * If you make modifications to this software that you feel increases
- * it usefulness for the rest of the community, please email the
- * changes, enhancements, bug fixes as well as any and all ideas to me.
- * This software is going to be maintained and enhanced as deemed
- * necessary by the community.
- *
- * Mark Hessling email: M.Hessling@gu.edu.au
- * 36 David Road Phone: +61 7 849 7731
- * Holland Park Fax: +61 7 875 5314
- * QLD 4121
- * Australia
- */
-
- /*
- $Id: box.c 2.0 1995/01/26 16:29:44 MH Release MH $
- */
-
- #include <stdio.h>
-
- #include "the.h"
- #include "proto.h"
-
- /*#define DEBUG 1*/
- /***********************************************************************/
- #ifdef PROTO
- void box_operations(short action,CHARTYPE reset,bool overlay,CHARTYPE fillchar)
- #else
- void box_operations(action,reset,overlay,fillchar)
- short action;
- CHARTYPE reset;
- bool overlay;
- CHARTYPE fillchar;
- #endif
- /***********************************************************************/
- {
- /*-------------------------- external data ----------------------------*/
- extern VIEW_DETAILS *vd_mark;
- /*--------------------------- local data ------------------------------*/
- BOXP boxp;
- short rc=RC_OK;
- unsigned short y=0,x=0;
- LENGTHTYPE offset=0;
- short save_mark_type=MARK_VIEW->mark_type;
- /*--------------------------- processing ------------------------------*/
- #ifdef TRACE
- trace_function("commutil.c:box_operations");
- #endif
- /*---------------------------------------------------------------------*/
- /* This procedure is for copying, deleting, filling, moving and */
- /* overlaying box blocks. Box blocks consist of BOX, WORD and COLUMN */
- /* blocks. */
- /*---------------------------------------------------------------------*/
- post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line);
- /*---------------------------------------------------------------------*/
- /* If the command was issued on the command line then the destination */
- /* line is the current line and the destination column is 0; */
- /*---------------------------------------------------------------------*/
- if (CURRENT_VIEW->current_window == WINDOW_COMMAND)
- {
- if (CURRENT_VIEW->current_line == 0L)
- boxp.dst_start_line = 1L;
- else
- boxp.dst_start_line = CURRENT_VIEW->current_line;
- boxp.dst_start_col = 0;
- }
- else
- {
- if (CURRENT_VIEW->focus_line == 0L)
- boxp.dst_start_line = 1L;
- else
- boxp.dst_start_line = CURRENT_VIEW->focus_line;
- getyx(CURRENT_WINDOW,y,x);
- boxp.dst_start_col = x + CURRENT_VIEW->verify_col-1;
- }
-
- boxp.src_start_line = MARK_VIEW->mark_start_line;
- boxp.src_start_col = MARK_VIEW->mark_start_col-1;
-
- boxp.num_cols = MARK_VIEW->mark_end_col - MARK_VIEW->mark_start_col + 1;
- /*---------------------------------------------------------------------*/
- /* If the block type is COLUMN, the number of lines to operate on is */
- /* the number of lines in the source file and the destination start */
- /* line is line 1. Reset these values set above. */
- /*---------------------------------------------------------------------*/
- if (MARK_VIEW->mark_type == M_COLUMN)
- {
- boxp.num_lines = MARK_VIEW->file_for_view->number_lines - boxp.src_start_line +1L;
- boxp.dst_start_line = 1L;
- }
- else
- boxp.num_lines = MARK_VIEW->mark_end_line - boxp.src_start_line +1L;
- /*---------------------------------------------------------------------*/
- /* Find the current LINE pointer for both the source and destination */
- /* lines. */
- /*---------------------------------------------------------------------*/
- boxp.curr_src = lll_find(MARK_FILE->first_line,boxp.src_start_line);
- if (action != BOX_D)
- boxp.curr_dst = lll_find(CURRENT_FILE->first_line,boxp.dst_start_line);
- /*---------------------------------------------------------------------*/
- /* Call the appropriate box function... */
- /*---------------------------------------------------------------------*/
- boxp.action = action;
- switch(action)
- {
- case BOX_D:
- rc = box_delete(&boxp);
- break;
- case BOX_M:
- rc = box_move(&boxp,overlay);
- break;
- case BOX_C:
- /* rc = box_copy(&boxp,overlay);*/
- rc = box_move(&boxp,overlay);
- break;
- case BOX_F:
- rc = box_fill(&boxp,fillchar);
- break;
- }
- if ((rc = increment_alt(CURRENT_FILE)) != RC_OK)
- {
- #ifdef TRACE
- trace_return();
- #endif
- return; /* should return a value */
- }
- /*---------------------------------------------------------------------*/
- /* Set the parameters in the MARK_VIEW to OFF; */
- /*---------------------------------------------------------------------*/
- MARK_VIEW->marked_line = MARK_VIEW->marked_col = FALSE;
- MARK_VIEW = (VIEW_DETAILS *)NULL;
- /*---------------------------------------------------------------------*/
- /* If we are not resetting the block, set up block markers... */
- /*---------------------------------------------------------------------*/
- if (reset != SOURCE_BLOCK_RESET)
- {
- if (boxp.src_start_col < boxp.dst_start_col
- && action == BOX_M)
- offset = boxp.num_cols;
- MARK_VIEW = CURRENT_VIEW;
- MARK_VIEW->mark_start_line = boxp.dst_start_line;
- MARK_VIEW->mark_end_line = boxp.dst_start_line+boxp.num_lines-1L;
- MARK_VIEW->mark_start_col = boxp.dst_start_col+1-offset;
- MARK_VIEW->mark_end_col = boxp.dst_start_col+boxp.num_cols-offset;
- MARK_VIEW->mark_type = save_mark_type;
- MARK_VIEW->marked_line = MARK_VIEW->marked_col = TRUE;
- wmove(CURRENT_WINDOW,y,x-offset);
- }
- pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line);
- build_current_screen();
- display_current_screen(); /* should only call this is the marked block is in view */
- #ifdef TRACE
- trace_return();
- #endif
- return;
- }
- /***********************************************************************/
- #ifdef PROTO
- short box_delete(BOXP *prm)
- #else
- short box_delete(prm)
- BOXP *prm;
- #endif
- /***********************************************************************/
- {
- /*-------------------------- external data ----------------------------*/
- extern VIEW_DETAILS *vd_mark;
- /*--------------------------- local data ------------------------------*/
- LINETYPE i=0L;
- LENGTHTYPE j=0;
- short num_to_move=0;
- /*--------------------------- processing ------------------------------*/
- #ifdef TRACE
- trace_function("commutil.c:box_delete");
- #endif
- for (i=0L;i<prm->num_lines;i++)
- {
- num_to_move = prm->curr_src->length - MARK_VIEW->mark_end_col;
- if (num_to_move < 0)
- num_to_move = 0;
- add_to_recovery_list(prm->curr_src->line,prm->curr_src->length);
- prm->curr_src->length = min(prm->curr_src->length,prm->src_start_col+num_to_move);
- for (j=0;j<num_to_move;j++)
- *(prm->curr_src->line+j+prm->src_start_col) = *(prm->curr_src->line+prm->src_start_col+j+prm->num_cols);
- *(prm->curr_src->line+prm->curr_src->length) = '\0';/* null terminate */
- prm->curr_src = prm->curr_src->next; /* this should NEVER go past the end */
- }
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_OK);
- }
- /***********************************************************************/
- #ifdef PROTO
- short box_move(BOXP *prm,bool overlay)
- #else
- short box_move(prm,overlay)
- BOXP *prm;
- bool overlay;
- #endif
- /***********************************************************************/
- {
- /*-------------------------- external data ----------------------------*/
- extern CHARTYPE *rec;
- extern unsigned short rec_len;
- /*--------------------------- local data ------------------------------*/
- LINETYPE i=0L;
- LINE *first_save=NULL,*save_src=NULL,*tmp=NULL;
- bool copy_first=FALSE;
- LINETYPE save_src_start_line=0L;
- LENGTHTYPE save_src_start_col=0;
- /*--------------------------- processing ------------------------------*/
- #ifdef TRACE
- trace_function("commutil.c:box_move");
- #endif
- if (prm->dst_start_col > prm->src_start_col+prm->num_cols)
- copy_first = TRUE;
- save_src_start_col = prm->src_start_col;
- save_src_start_line = prm->src_start_line;
- if (copy_first)
- {
- save_src = prm->curr_src;
- box_copy(prm,overlay);
- prm->src_start_line = save_src_start_line;
- prm->src_start_col = save_src_start_col;
- prm->curr_src = save_src;
- if (prm->action == BOX_M)
- box_delete(prm);
- }
- else
- {
- /*---------------------------------------------------------------------*/
- /* Save the data that is to be deleted. It is saved in a format that */
- /* can be used in copy_box() as the src line pointer. */
- /*---------------------------------------------------------------------*/
- tmp = prm->curr_src;
- for (i=0L;i<prm->num_lines;i++)
- {
- memset(rec,' ',max_line_length); /* copy line into rec[] */
- memcpy(rec,tmp->line,tmp->length);
- rec_len = tmp->length;
- if ((save_src = add_line(first_save,save_src,
- rec+prm->src_start_col,prm->num_cols,0)) == (LINE *)NULL)
- {
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_OUT_OF_MEMORY);
- }
- if (first_save == (LINE *)NULL)
- first_save = save_src;
- tmp = tmp->next;
- }
- if (prm->action == BOX_M)
- box_delete(prm);
- prm->src_start_line = 0L;
- prm->src_start_col = 0;
- prm->curr_src = first_save;
- box_copy(prm,overlay);
- first_save = lll_free(first_save);
- prm->src_start_line = save_src_start_line;
- prm->src_start_col = save_src_start_col;
- }
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_OK);
- }
- /***********************************************************************/
- #ifdef PROTO
- short box_copy(BOXP *prm,bool overlay)
- #else
- short box_copy(prm,overlay)
- BOXP *prm;
- bool overlay;
- #endif
- /***********************************************************************/
- {
- /*-------------------------- external data ----------------------------*/
- extern CHARTYPE *rec;
- extern unsigned short rec_len;
- /*--------------------------- local data ------------------------------*/
- LINETYPE i=0L;
- LENGTHTYPE j=0;
- CHARTYPE chr=0;
- short rc=RC_OK;
- /*--------------------------- processing ------------------------------*/
- #ifdef TRACE
- trace_function("commutil.c:box_copy");
- #endif
- for (i=0L;i<prm->num_lines;i++)
- {
- if (prm->curr_dst->next == (LINE *)NULL) /* on *** Bottom of File *** */
- {
- if ((prm->curr_dst = add_line(CURRENT_FILE->first_line,prm->curr_dst->prev,
- (CHARTYPE *)"",0,0)) == (LINE *)NULL)
- {
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_OUT_OF_MEMORY);
- }
- CURRENT_FILE->number_lines++;
- }
- pre_process_line(CURRENT_VIEW,prm->dst_start_line+i);/* copy dest line into rec */
- for (j=0;j<prm->num_cols;j++)
- {
- if (prm->src_start_col+j+1 > prm->curr_src->length)
- chr = (CHARTYPE)' ';
- else
- chr = (CHARTYPE)*(prm->curr_src->line+prm->src_start_col+j);
- if (overlay)
- rec[prm->dst_start_col+j] = chr;
- else
- meminschr(rec,chr,prm->dst_start_col+j,max_line_length,rec_len++);
- }
- rc = memrevne(rec,' ',max_line_length);
- if (rc == (-1))
- rec_len = 0;
- else
- rec_len = rc+1;
- post_process_line(CURRENT_VIEW,prm->dst_start_line+i);
- prm->curr_src = prm->curr_src->next; /* this should NEVER go past the end */
- prm->curr_dst = prm->curr_dst->next; /* this should NEVER go past the end */
- }
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_OK);
- }
- /***********************************************************************/
- #ifdef PROTO
- short box_fill(BOXP *prm,CHARTYPE fillchar)
- #else
- short box_fill(prm,fillchar)
- BOXP *prm;
- CHARTYPE fillchar;
- #endif
- /***********************************************************************/
- {
- /*-------------------------- external data ----------------------------*/
- extern CHARTYPE *rec;
- extern unsigned short rec_len;
- /*--------------------------- local data ------------------------------*/
- LINETYPE i=0L;
- LENGTHTYPE j=0;
- short rc=RC_OK;
- /*--------------------------- processing ------------------------------*/
- #ifdef TRACE
- trace_function("commutil.c:box_fill");
- #endif
- for (i=0L;i<prm->num_lines;i++)
- {
- pre_process_line(CURRENT_VIEW,prm->src_start_line+i);/* copy source line into rec */
- for (j=0;j<prm->num_cols;j++)
- rec[prm->src_start_col+j] = fillchar;
- rc = memrevne(rec,' ',max_line_length);
- if (rc == (-1))
- rec_len = 0;
- else
- rec_len = rc+1;
- post_process_line(CURRENT_VIEW,prm->src_start_line+i);
- prm->curr_src = prm->curr_src->next; /* this should NEVER go past the end */
- }
-
- prm->dst_start_col = prm->src_start_col;
- prm->dst_start_line = prm->src_start_line;
-
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_OK);
- }
-